package com.fany.fastsearcher.activity;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;

import com.fany.constants.StringResources;
import com.fany.filesearcher.*;
import com.fany.fastsearcher.R;
import com.fany.utils.BitmapHelper;
import com.fany.utils.CommonUtils;
import com.fany.utils.FileHelper;
import com.fany.views.circlemenu.CircleMenuItem;
import com.fany.views.circlemenu.CircleMenuViewAdvanced;
import com.fany.views.circlemenu.OnAngleChangedListener;
import com.fany.views.circlemenu.OnButtonClickListener;
import com.fany.views.controls.ListViewAdapter;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.*;

public class FileListActivity extends ListViewActivity implements AdapterView.OnItemSelectedListener,
        OnAngleChangedListener, OnButtonClickListener
{

    private static final int OpenFile = 0x100;
    private static final int DeleteFile = 0x101;
    private static final int FileProperty = 0x102;
    private static final int RenameFile = 0x103;
    private static final int Exit = 0x200;

    private static final int StepAngle = 45;
    private ListViewAdapter _adapter;
    private CircleMenuViewAdvanced _menuView;

    public void upward(View view)
    {
        if (!_path.equals("/"))
        {
            String name = FileHelper.extractFileName(_path);
            _path = FileHelper.extractDirectoryName(_path);
            loadFiles(name);
        }
    }

    @Override
    protected int getListViewID()
    {
        return R.id.list_include_files;
    }

    @Override
    protected int getContentViewID()
    {
        return R.layout.filelist_activity;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        _activity = this;
        _path = getIntent().getStringExtra("path");
        _recorder = new SQLiteFileRecorder(this);

        Spinner spinner = (Spinner) findViewById(R.id.spin_files);
        spinner.setOnItemSelectedListener(this);

        loadFiles(FileHelper.extractFileName(_path));

        createCircleMenuView();
        new Thread(new CommandWatchThread()).start();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK)
        {
            if (_menuView.getIsShowMenus())
            {
                _menuView.setIsShowMenus(false);
                return true;
            }
            else
            {
                Intent data = new Intent();
                Bundle bundle = new Bundle();
                bundle.putString("path", _path);
                data.putExtras(bundle);
                setResult(RESULT_OK, data);
                finish();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }


    private void createCircleMenuView()
    {
        _menuView = new CircleMenuViewAdvanced(this);
        WindowManager.LayoutParams windowManagerParams;
        _menuView.setIsShowMenus(false);
        _menuView.setRingColor(Color.YELLOW, Color.RED);
        _menuView.addItem(StringResources.Open, R.drawable.file_open, OpenFile);
        _menuView.addItem(StringResources.Delete, R.drawable.file_delete, DeleteFile);
        _menuView.addItem(StringResources.Property, R.drawable.file_infomation, FileProperty);
        _menuView.addItem(StringResources.Rename, R.drawable.file_rename, RenameFile);
        _menuView.addItem(StringResources.Exit, R.drawable.file_exit, Exit);

        windowManagerParams = new WindowManager.LayoutParams();
        windowManagerParams.type = WindowManager.LayoutParams.MATCH_PARENT;
        windowManagerParams.format = PixelFormat.RGBA_8888;
        windowManagerParams.gravity = Gravity.LEFT | Gravity.TOP;
        addContentView(_menuView, windowManagerParams);

        _menuView.angleChangedListener = this;
        _menuView.buttonClickListener = this;
    }

    private int _angleOffset;

    @Override
    public boolean onAngleChanged(int angle)
    {
        int maxAngleOffset = StepAngle * _items.size();
        _angleOffset = Math.min(Math.max(0, _angleOffset + angle), maxAngleOffset);
        int index = Math.min(_angleOffset / StepAngle, getListView().getCount() - 1);

        int selectedIndex = _adapter.getSelectedIndex();
        if (selectedIndex != index)
        {
            updateSelectedIndex(index);
        }
//        LogHelper.logDebugInfo("angle:" + angle + "; _angleOffset" + _angleOffset);
        return true;
    }

    @Override
    protected void onItemClick(int index)
    {
        updateSelectedIndex(index);
        openFile();
    }

    @Override
    protected void onItemLongClick(int index)
    {
        updateSelectedIndex(index);
        _menuView.setIsShowMenus(true);
    }

    @Override
    public boolean onButtonClick()
    {
        if (!_menuView.getIsShowMenus())
        {
            _menuView.setIsShowMenus(true);
        }
        return true;
    }

    private void openFile()
    {
        if (_adapter.getSelectedIndex() == -1)
        {
            CommonUtils.showToast(getApplicationContext(), StringResources.PleaseSelectFile);
            return;
        }
        String path = FileHelper.combineFileName(_path, (String) _items.get(_adapter.getSelectedIndex()).get("name"));
        if (FileHelper.isDirectory(path))
        {
            _path = path;
            loadFiles("");
        }
        else
        {
            Intent intent = FileHelper.openFileIntent(path);
            startActivity(intent);
        }
    }

    private Handler _handler = new CommandHandler(this);

    private static class CommandHandler extends Handler
    {
        private WeakReference<FileListActivity> _activity;

        public CommandHandler(FileListActivity activity)
        {
            _activity = new WeakReference<FileListActivity>(activity);
        }

        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case DeleteFile:
                    _activity.get().deleteFile();
                    break;
                case FileProperty:
                    _activity.get().showFileInfo();
                    break;
                case RenameFile:
                    _activity.get().renameFile();
                    break;
                case OpenFile:
                    _activity.get().openFile();
                    break;
            }
            _activity.get()._menuView.setIsShowMenus(false);
            super.handleMessage(msg);
        }
    }

    class CommandWatchThread implements Runnable
    {
        public void run()
        {
            while (!Thread.currentThread().isInterrupted())
            {
                CircleMenuItem item = _menuView.getTouchedItem();
                if (item != null)
                {
                    Message message = new Message();
                    message.what = item.commandId;
                    _handler.sendMessage(message);
                }
                try
                {
                    _menuView.cleanTouchedItem();
                    Thread.sleep(10);
                }
                catch (InterruptedException e)
                {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }

    // AdapterView.OnItemSelectedListener
    @Override
    public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l)
    {
        String[] paths = _path.split(File.separator);
        String name = "";
        if (paths.length == 0)
        {
            paths = new String[1];
        }
        paths[0] = File.separator;
        String path = File.separator;
        for (int i = 1; i <= pos; i++)
        {
            path += paths[i] + File.separator;
        }
        if (!path.equals(File.separator) && path.endsWith(File.separator))
        {
            path = path.substring(0, path.length() - 1);
        }
        if (paths.length > pos + 1)
        {
            name = paths[pos + 1];
        }
        if (!path.equals(_path))
        {
            _path = path;
            loadFiles(name);
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> adapterView)
    {
    }

    private void loadFiles(String focusFileName)
    {
        List<String> rets;
        if (!FileHelper.isDirectory(_path))
        {
            _path = FileHelper.extractDirectoryName(_path);
        }
        rets = FileHelper.enumFiles(_path);
        _items = new ArrayList<HashMap<String, Object>>();
        HashMap<String, Object> focusItem = null;
        for (String name : rets)
        {
            HashMap<String, Object> item = new HashMap<String, Object>();
            item.put("name", name);
            item.put("path", FileHelper.combineFileName(_path, name));
            File file = new File(FileHelper.combineFileName(_path, name));
            if (file.isDirectory())
            {
                item.put("image", R.drawable.folder);
            }
            else
            {
                item.put("image", item.get("path"));
            }
            _items.add(item);
            if (!focusFileName.isEmpty() && focusFileName.equals(name))
            {
                focusItem = item;
            }
        }
        _adapter = new ListViewAdapter(this, _items, R.layout.filelist_liststyle, new String[]{
                "name", "image", "path"
        }, new int[]{
                R.id.filelist_liststyle_content, R.id.filelist_liststyle_icon,
                R.id.filelist_liststyle_path
        });
        _adapter.setViewBinder(new ListViewAdapter.ViewBinder()
        {
            @Override
            public boolean setViewValue(View view, Object data, String textRepresentation)
            {
                if (view instanceof ImageView && data instanceof String)
                {
                    ImageView iv = (ImageView) view;
                    if (iv.getTag() == null)
                    {
                        iv.setTag(data.toString());
                        BitmapHelper.loadThumbnailAsync(data.toString(), 64, iv);
                    }
                    return true;
                }
                return false;
            }
        });
        getListView().setAdapter(_adapter);
        if (_items.size() > 0)
        {
            if (focusItem == null)
            {
                updateSelectedIndex(0);
            }
            else
            {
                updateSelectedIndex(_items.indexOf(focusItem));
            }
        }

        String[] paths = _path.split(File.separator);
        if (paths.length == 0)
        {
            paths = new String[1];
        }
        paths[0] = File.separator;
        Spinner spinner = (Spinner) findViewById(R.id.spin_files);
        spinner.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, paths));
        spinner.setSelection(paths.length - 1);
    }

    private void updateSelectedIndex(int index)
    {
        _angleOffset = index * StepAngle;
        if (_adapter == null)
        {
            return;
        }
        _adapter.setSelectedIndex(index);
        _adapter.notifyDataSetChanged();
        setPosition(index);
    }

    private void deleteFile()
    {
        if (_adapter.getSelectedIndex() == -1)
        {
            CommonUtils.showToast(getApplicationContext(), StringResources.PleaseSelectFile);
            return;
        }
        final String path = (String) _items.get(_adapter.getSelectedIndex()).get("path");
        String title = "";
        String message = "";
        if (FileHelper.isDirectory(path))
        {
            title = StringResources.ConfirmDeleteFolderTitle;
            message = String.format(StringResources.ConfirmDeleteFolderMessage, path);
        }
        else
        {
            title = StringResources.ConfirmDeleteFileTitle;
            message = String.format(StringResources.ConfirmDeleteFileMessage, path);
        }
        _operatingPath = path;
        CommonUtils.confirm(this, title, message, new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                FileDeleteThread thread = new FileDeleteThread(_operatingPath);
                thread.start();
                dialog.dismiss();
            }
        });
    }

    private void renameFile()
    {
        if (_adapter.getSelectedIndex() == -1)
        {
            CommonUtils.showToast(getApplicationContext(), StringResources.PleaseSelectFile);
            return;
        }
        final String renamePath = (String) _items.get(_adapter.getSelectedIndex()).get("path");
        final String originName = (String) _items.get(_adapter.getSelectedIndex()).get("name");
        final Context context = this;
        CommonUtils.inputDialog(this, StringResources.PleaseInputNewName, originName,
                new CommonUtils.InputDialogOKCallback()
                {
                    @Override
                    public void onOk(String inputResult)
                    {
                        if (!inputResult.isEmpty())
                        {
                            StringBuffer newPath = new StringBuffer();
                            if (FileHelper.renameFile(renamePath, inputResult, newPath))
                            {
                                loadFiles(inputResult);
                                _recorder.unRecord(renamePath);
                                _recorder.record(Arrays.asList(new String[]{newPath.toString()}));
                            }
                        }
                        else
                        {
                            CommonUtils.showMessage(context, StringResources.NameCantEmpty);
                        }
                    }
                },
                null);
    }

    private void showFileInfo()
    {
        String path;
        if (_adapter.getSelectedIndex() == -1)
        {
            path = _path;
        }
        else
        {
            path = (String) _items.get(_adapter.getSelectedIndex()).get("path");
        }

        Intent intent = new Intent(getBaseContext(), FileDetailActivity.class);
        intent.putExtra("path", path);
        startActivity(intent);
    }

    private String _path;
    private String _operatingPath;
    private ArrayList<HashMap<String, Object>> _items;
    private SQLiteFileRecorder _recorder;
    private ProgressDialog _progressDlg;
    private Activity _activity;
    private String _operatingResult;
    private Handler _fileDeleteHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            if (msg.what == -1)
            {
                String processTitle = StringResources.Hint;
                String processHint = StringResources.IsDeleting + _operatingPath;
                _progressDlg = ProgressDialog.show(_activity, processTitle, processHint);
            }
            else if (msg.what == 0)
            {
                if (_progressDlg.isShowing())
                {
                    loadFiles("");
                    _progressDlg.dismiss();
                    CommonUtils.showToast(_activity, _operatingResult);
                }
            }
            else if (msg.what == 1)
            {
                _progressDlg.dismiss();
                CommonUtils.showToast(getApplicationContext(), _operatingResult);
            }
        }
    };

    private class FileDeleteThread extends Thread
    {
        private String _deletePath;

        public FileDeleteThread(String path)
        {
            _deletePath = path;
        }

        @Override
        public void run()
        {
            try
            {
                _fileDeleteHandler.sendEmptyMessage(-1);
                FileHelper.deleteDirectory(_deletePath);
                _recorder.unRecord(_deletePath);
                _operatingResult = StringResources.DeleteSuccess;
                _fileDeleteHandler.sendEmptyMessage(0);
            }
            catch (Exception ex)
            {
                _operatingResult = ex.getMessage();
                _fileDeleteHandler.sendEmptyMessage(1);
            }
        }
    }
}
